<!doctype html>

<head>
  <meta charset="UTF-8" />
  <link class="ico" rel="icon" type="image/svg+xml" href="favicon.ico" />
  <link rel="manifest" href="manifest.json" />
  <meta
    class="meta-og-image"
    property="og:image"
    content="./nested/asset.png"
  />
</head>

<link class="data-href" rel="icon" href="data:," />
<link rel="stylesheet" href="/raw.css" />

<h1>Assets</h1>

<p class="base"></p>

<h2>Raw References from publicDir</h2>
<ul>
  <li class="raw-js"></li>
  <script src="/raw.js"></script>
  <li class="raw-css">
    Raw CSS from publicDir should load (this should be red)
  </li>
</ul>

<h2>Asset Imports from JS</h2>
<ul>
  <li>Relative: <code class="asset-import-relative"></code></li>
  <li>Absolute: <code class="asset-import-absolute"></code></li>
  <li>From publicDir: <code class="public-import"></code></li>
  <li>
    From publicDir (json): <code class="public-json-import"></code> Content:
    <code class="public-json-import-content"></code>
  </li>
  <li>
    From publicDir (js): <code class="public-js-import"></code> Content:
    <code class="public-js-import-content"></code> Content-Type:
    <code class="public-js-import-content-type"></code>
  </li>
  <li>
    From publicDir (ts): <code class="public-ts-import"></code> Content:
    <code class="public-ts-import-content"></code> Content-Type:
    <code class="public-ts-import-content-type"></code>
  </li>
  <li>
    From publicDir (mts): <code class="public-mts-import"></code> Content:
    <code class="public-mts-import-content"></code> Content-Type:
    <code class="public-mts-import-content-type"></code>
  </li>
</ul>

<h2>CSS url references</h2>
<div>Font should be loaded (all text should be italic)</div>
<div class="css-url-absolute">
  <span style="background: #fff">CSS background (absolute)</span>
</div>
<div class="css-url-relative">
  <span style="background: #fff">CSS background (relative)</span>
</div>
<div class="css-url-encoded">
  <span style="background: #fff">CSS background (encoded)</span>
</div>
<div class="css-image-set-relative">
  <span style="background: #fff"
    >CSS background with image-set() (relative)</span
  >
</div>
<div class="css-image-set-without-url-call">
  <span style="background: #fff"
    >CSS background with image-set() (relative)</span
  >
</div>
<div class="css-image-set-with-var">
  <span style="background: #fff">
    CSS background image-set() (relative in var)
  </span>
</div>
<div class="css-image-set-mix-url-var">
  <span style="background: #fff">
    CSS background image-set() (mix var and url)
  </span>
</div>
<div class="css-image-set-base64">
  <span style="background: #fff">
    CSS background image-set() (with base64)
  </span>
</div>
<div class="css-image-set-gradient">
  <span style="background: #fff">
    CSS background image-set() (with gradient)
  </span>
</div>
<div class="css-image-set-multiple-descriptor">
  <span style="background: #fff">
    CSS background image-set() (with multiple descriptor)
  </span>
</div>
<div
  class="css-image-set-multiple-descriptor-inline-style"
  style="
    background-image: -webkit-image-set(
      './nested/asset.png' type('image/png') 1x,
      './nested/asset.png' type('image/png') 2x
    );
    background-size: 10px;
  "
>
  <span style="background: #fff">
    CSS background image-set() inline style (with multiple descriptor)
  </span>
</div>
<div
  class="image-set-and-url-exsiting-at-same-time"
  style="
    background-image:
      image-set(url('./nested/asset.png')), url('./nested/asset.png');
    background-size: 10px 10px;
  "
>
  <span style="background: #fff"
    >CSS background image-set() and url existing at the same time</span
  >
</div>
<div class="css-url-relative-at-imported">
  <span style="background: #fff"
    >CSS background (relative from @imported file in different dir)</span
  >
</div>
<div class="css-url-public">
  <span style="background: #fff">CSS background (public)</span>
</div>
<div class="css-url-data-uri">
  <span style="background: #fff">CSS background (data URI)</span>
</div>
<div class="css-url-base64-inline">
  <span style="background: #fff">CSS background (base64 inline in prod)</span>
</div>
<div class="css-url-quotes-base64-inline">
  <span style="background: #fff">CSS background (base64 inline in prod)</span>
</div>
<div class="css-url-same-line">
  <span style="background: #fff"
    >CSS background (multiple urls on same line)</span
  >
</div>
<div class="css-url-aliased">
  <span style="background: #fff">CSS background (aliased)</span>
</div>
<div class="css-url-preinlined-svg">
  <span style="background: #fff">CSS background (pre inlined SVG)</span>
</div>
<div class="css-manual-chunks-relative">
  <span style="background: #fff"
    >CSS nested manual chunks relative base background</span
  >
</div>

<div class="css-url-svg">
  <span style="background: #fff">CSS SVG background</span>
</div>
<div class="css-url-svg-in-url">
  <span style="background: #fff">CSS (?url) SVG background</span>
</div>

<div class="css-image-set-svg">
  <span style="background: #fff">CSS SVG background with image-set</span>
</div>

<div class="css-url-non-inline-hmr">
  <span style="background: #fff">CSS non-inlined background HMR</span>
</div>

<h2>Unicode URL</h2>
<div>
  <code class="unicode-url"></code>
  <img src="./nested/テスト-測試-white space.png" />
</div>

<h2>Filename including single quote</h2>
<div>
  <code class="filename-including-single-quote"></code>
</div>

<h2>Filename including percent</h2>
<div>
  <code class="percent-url"></code>
  <img src="./asset/percent%25.png" />
</div>

<h2>encodeURI for the address</h2>
<div>
  <img
    class="encodeURI"
    src="./nested/%E3%83%86%E3%82%B9%E3%83%88-%E6%B8%AC%E8%A9%A6-white%20space.png"
  />
</div>

<h2>Image Src Set</h2>
<div>
  <img
    class="img-src-set"
    src="./nested/asset.png"
    srcset="./nested/asset.png 1x, ./nested/asset.png 2x"
    alt=""
  />
  <img
    class="img-src-set-public"
    src="/icon space.png"
    srcset="/icon.png 1x, /icon.png 2x"
    alt=""
  />
  <img
    class="img-src-set-mixed"
    src="/icon.png"
    srcset="https://vite.dev/logo-with-shadow.png 1x, ./nested/asset.png 2x"
    alt=""
  />
</div>

<h2>HTML only asset</h2>
<div>
  <img class="img-src" src="./nested/html-only-asset.jpg" alt="" />
</div>

<h2>HTML inline asset</h2>
<div>
  <img class="img-src-inline" src="./nested/inlined.svg" alt="" />
</div>

<h2>SVG Fragments</h2>
<div>
  <img
    class="svg-frag-img"
    src="./nested/fragment.svg#icon-clock-view"
    alt=""
  />
  <img
    class="svg-frag-img"
    src="./nested/fragment.svg#icon-heart-view"
    alt=""
  />
  <img
    class="svg-frag-img"
    src="./nested/fragment.svg#icon-arrow-right-view"
    alt=""
  />
</div>

<h2>SVG Fragments via CSS background url</h2>
<div>
  <span class="icon icon-clock"></span>
  <span class="icon icon-heart"></span>
  <span class="icon icon-arrow-right"></span>
  <span class="icon icon-clock-alias"></span>
</div>

<h2>SVG Fragments via JS Import</h2>
<div>
  <p>Imported path: <code class="svg-frag-import-path"></code></p>
  <img class="svg-frag-import" alt="" />
</div>

<h2>Unknown extension assets import</h2>
<code class="unknown-ext"></code>

<h2>?raw import</h2>
<code class="raw"></code>
<code class="raw-html"></code>

<h2>?no-inline svg import</h2>
<code class="no-inline-svg"></code>

<h2>?no-inline svg import -- multiple postfix</h2>
<code class="no-inline-svg-mp"></code>

<h2>?inline png import</h2>
<code class="inline-png"></code>

<h2>?inline public png import</h2>
<code class="inline-public-png"></code>

<h2>?url&inline public json import</h2>
<code class="inline-public-json"></code>

<h2>?url import</h2>
<code class="url"></code>

<h2>?url import with css</h2>
<code class="url-css"></code>

<h2>new URL('...', import.meta.url)</h2>
<img class="import-meta-url-img" />
<code class="import-meta-url"></code>

<h2>new URL('@/...', import.meta.url)</h2>
<img class="import-meta-url-dep-img" />
<code class="import-meta-url-dep"></code>

<h2>new URL('/...', import.meta.url)</h2>
<img class="import-meta-url-base-path-img" />
<code class="import-meta-url-base-path"></code>

<h2>new URL('data:...', import.meta.url)</h2>
<img class="import-meta-url-data-uri-img" />
<code class="import-meta-url-data-uri"></code>

<h2>new URL('...', import.meta.url (without extension))</h2>
<p>
  <code class="import-meta-url-content-without-extension"></code>
</p>
<p>
  <code class="import-meta-url-without-extension"></code>
</p>

<h2>new URL('...', import.meta.url,) (with comma)</h2>
<img class="import-meta-url-img-comma" />
<code class="import-meta-url-comma"></code>

<h2>new URL('...', import.meta.url,) (with comma + new line)</h2>
<img class="import-meta-url-img-comma-nl" />
<code class="import-meta-url-comma-nl"></code>

<h2>new URL(`./${dynamic}`, import.meta.url)</h2>
<p>
  <img class="dynamic-import-meta-url-img-1" />
  <code class="dynamic-import-meta-url-1"></code>
</p>
<p>
  <img class="dynamic-import-meta-url-img-2" />
  <code class="dynamic-import-meta-url-2"></code>
</p>
<p>
  <code class="dynamic-import-meta-url-js"></code>
</p>

<h2>new URL(`./${dynamic}`, import.meta.url,) (with comma)</h2>
<p>
  <img class="dynamic-import-meta-url-img-1-comma" />
  <code class="dynamic-import-meta-url-1-comma"></code>
</p>
<p>
  <img class="dynamic-import-meta-url-img-2-comma" />
  <code class="dynamic-import-meta-url-2-comma"></code>
</p>

<h2>new URL(`./${dynamic}?abc`, import.meta.url)</h2>
<p>
  <img class="dynamic-import-meta-url-img-1-query" />
  <code class="dynamic-import-meta-url-1-query"></code>
</p>
<p>
  <img class="dynamic-import-meta-url-img-2-query" />
  <code class="dynamic-import-meta-url-2-query"></code>
</p>

<h2>new URL(`./${1 === 0 ? static : dynamic}?abc`, import.meta.url)</h2>
<p>
  <img class="dynamic-import-meta-url-img-1-ternary" />
  <code class="dynamic-import-meta-url-1-ternary"></code>
</p>
<p>
  <img class="dynamic-import-meta-url-img-2-ternary" />
  <code class="dynamic-import-meta-url-2-ternary"></code>
</p>

<h2>new URL(/* @vite-ignore */ 'non-existent', import.meta.url)</h2>
<p>
  <code class="non-existent-import-meta-url"></code>
</p>

<h2>new URL(`${dynamic}`, import.meta.url)</h2>
<p>
  <code class="dynamic-import-meta-url-all"></code>
</p>

<h2>Multiline new URL(..., import.meta.url)</h2>
<code class="import-meta-url-multiline"></code>

<h2>simple script tag import-expression</h2>
<code class="import-expression"></code>
<code class="obj-import-express"></code>
<code class="string-import-express"></code>
<script>
  const obj = {
    import(t) {
      text('.obj-import-express', t)
    },
  }
  const stringImport = "const t = import('package')"
  function text(el, text) {
    document.querySelector(el).textContent = text
  }
  import('./static/import-expression.js')
  import('/import-expression.js')
  // import('./static/raw.js')
  /* import('./static/raw.js') */
  obj.import('ignore object import prop')
  try {
    text('.string-import-express', t)
  } catch {
    text('.string-import-express', 'no load')
  }
</script>
<h2>url in style tag</h2>
<h3>url</h3>
<style class="style-url">
  .style-url-assets {
    background: url('./nested/asset.png');
    background-size: 10px 10px;
  }
</style>
<div
  class="inline-style"
  style="background: url('./nested/asset.png'); background-size: 10px 10px"
>
  inline style
</div>
<div class="style-url-assets">use style class</div>

<h3>base64</h3>
<style class="style-base64">
  .style-base64-assets {
    background: url('./static/icon.png');
  }
</style>
<p class="inline-style-base64" style="background: url(./static/icon.png)">
  inline style
</p>
<p class="style-base64-assets">use style class</p>
<h3>from publicDir</h3>
<style>
  .style-public-assets {
    background: url('/icon.png');
  }
</style>
<p class="inline-style-public" style="background: url(/icon.png)">
  inline style
</p>
<p class="style-public-assets">use style class</p>

<h3 class="import-css">@import</h3>
<style class="style-import">
  @import url('./css/import.css');
</style>

<h3 class="foo-public">
  @import CSS from publicDir should load (this should be red)
</h3>
<h3 id="foo">import module css</h3>

<h3 class="raw-query"></h3>

<h3>style in svg</h3>
<svg viewBox="0 0 512 512" width="21" height="21" class="style-insvg">
  <style>
    .style-insvg-color {
      fill: #0088ff;
    }
  </style>
  <g class="style-insvg-color">
    <rect x="224" y="352" width="64" height="64" />
    <path
      d="M128 128v96h64v-96h96v96h-32v32h-32v64h64v-64h64V128h-32V96H160v32h-32z"
    />
  </g>
</svg>

<h3>assets in noscript</h3>
<noscript>
  <img class="noscript" src="./nested/asset.png" />
</noscript>

<h3>assets in template</h3>
<template>
  <img class="template" src="./nested/asset.png" />
</template>

<link rel="stylesheet" href="asset/style.css" />
<div class="relative-css">link style</div>
<div class="relative-js"></div>
<script src="asset/main.js" type="module"></script>
<style>
  @import '/foo.css';
</style>

<script type="module">
  import './css/fonts.css'
  import './css/css-url.css'
  import './css/icons.css'
  import './css/manual-chunks.css'
  import { multilineUrl } from './multiline-import-meta-url.js'

  text('.base', `import.meta.${``}env.BASE_URL: ${import.meta.env.BASE_URL}`)

  import url from './nested/asset.png'
  text('.asset-import-relative', url)

  import absoluteUrl from '/nested/asset.png'
  text('.asset-import-absolute', absoluteUrl)

  import publicUrl from '/icon.png'
  text('.public-import', publicUrl)

  import publicJsonUrl from '/foo.json?url'
  text('.public-json-import', publicJsonUrl)
  ;(async () => {
    const res = await fetch(publicJsonUrl)
    text('.public-json-import-content', await res.text())
  })()

  import publicJsUrl from '/raw.js?url'
  text('.public-js-import', publicJsUrl)
  ;(async () => {
    const res = await fetch(publicJsUrl)
    text('.public-js-import-content', await res.text())
    text(
      '.public-js-import-content-type',
      await res.headers.get('Content-Type'),
    )
  })()

  import publicTsUrl from '/raw.ts?url'
  text('.public-ts-import', publicTsUrl)
  ;(async () => {
    const res = await fetch(publicTsUrl)
    text('.public-ts-import-content', await res.text())
    text(
      '.public-ts-import-content-type',
      await res.headers.get('Content-Type'),
    )
  })()

  import publicMtsUrl from '/raw.mts?url'
  text('.public-mts-import', publicMtsUrl)
  ;(async () => {
    const res = await fetch(publicMtsUrl)
    text('.public-mts-import-content', await res.text())
    text(
      '.public-mts-import-content-type',
      await res.headers.get('Content-Type'),
    )
  })()

  import svgFrag from './nested/fragment.svg'
  text('.svg-frag-import-path', svgFrag)
  document.querySelector('.svg-frag-import').src = svgFrag + '#icon-heart-view'

  import unknownExtUrl from './nested/foo.unknown'
  text('.unknown-ext', unknownExtUrl)

  import rawSvg from './nested/fragment.svg?raw'
  text('.raw', rawSvg)

  import rawHtml from './nested/partial.html?raw'
  text('.raw-html', rawHtml)
  import.meta.hot?.accept('./nested/partial.html?raw', (m) => {
    text('.raw-html', m.default)
  })

  import noInlineSvg from './nested/fragment.svg?no-inline'
  text('.no-inline-svg', noInlineSvg)

  import noInlineSvgMP from './nested/fragment.svg?no-inline&foo=bar'
  text('.no-inline-svg-mp', noInlineSvgMP)

  import inlinePng from './nested/asset.png?inline'
  text('.inline-png', inlinePng)

  import inlinePublicPng from '/icon.png?inline'
  text('.inline-public-png', inlinePublicPng)

  import inlinePublicJson from '/foo.json?url&inline'
  text('.inline-public-json', inlinePublicJson)

  import fooUrl from './foo.js?url'
  text('.url', fooUrl)

  import unicodeUrl from './テスト-測試-white space.js?url'
  text('.unicode-url', unicodeUrl)

  import filenameIncludingSingleQuoteUrl from "./nested/with-single'quote.png"
  text('.filename-including-single-quote', filenameIncludingSingleQuoteUrl)

  // TODO: is not supported yet (https://github.com/vitejs/vite/pull/16243)
  // import percentUrl from './asset/percent%25.png?url'
  // text('.percent-url', percentUrl)

  import cssUrl from './css/icons.css?url'
  text('.url-css', cssUrl)

  import cssUrlUrl from './css/css-url-url.css?url'
  const linkTag = document.createElement('link')
  linkTag.href = cssUrlUrl
  linkTag.rel = 'stylesheet'
  document.body.appendChild(linkTag)

  // const url = new URL('non_existent_file.png', import.meta.url)
  const metaUrl = new URL('./import-meta-url/img.png', import.meta.url)
  text('.import-meta-url', metaUrl)
  document.querySelector('.import-meta-url-img').src = metaUrl

  const metaUrlDep = new URL('@/asset.png', import.meta.url)
  text('.import-meta-url-dep', metaUrlDep)
  document.querySelector('.import-meta-url-dep-img').src = metaUrlDep

  // testing URLs for public assets served at the public base path
  // equivalent to `new URL(`${import.meta.env.BASE_URL}/icon.png`, import.meta.url)
  const metaUrlBasePath = new URL('/icon.png', import.meta.url)
  text('.import-meta-url-base-path', metaUrlBasePath)
  document.querySelector('.import-meta-url-base-path-img').src = metaUrlBasePath

  const metaUrlDataUri = new URL(
    '',
    import.meta.url,
  )
  text('.import-meta-url-data-uri', metaUrlDataUri)
  document.querySelector('.import-meta-url-data-uri-img').src = metaUrlDataUri

  const metaUrlWithoutExtension = new URL('./nested/test', import.meta.url)
  text('.import-meta-url-without-extension', metaUrlWithoutExtension)
  ;(async () => {
    const res = await fetch(metaUrlWithoutExtension)
    text('.import-meta-url-content-without-extension', await res.text())
  })()

  // prettier-ignore
  const metaUrlWithComma = new URL('./nested/asset.png', import.meta.url,)
  text('.import-meta-url-comma', metaUrlWithComma)
  document.querySelector('.import-meta-url-img-comma').src = metaUrlWithComma

  // testing trailing comma and new line
  // prettier-ignore
  const metaUrlWithCommaNL = new URL(
    './nested/asset.png',
    import.meta.url,
  )
  text('.import-meta-url-comma-nl', metaUrlWithCommaNL)
  document.querySelector('.import-meta-url-img-comma-nl').src =
    metaUrlWithCommaNL

  import classNames from './css/foo.module.css'
  document.querySelector('#foo').className = classNames['foo-module']

  import someString from './static/foo.txt?raw'
  document.querySelector('.raw-query').textContent = someString

  // NOTE: add `'' +` to opt-out rolldown's transform: https://github.com/rolldown/rolldown/issues/2745
  const metaUrlNonExistent = new URL(
    /* @vite-ignore */ 'non-existent',
    '' + import.meta.url,
  ).pathname
  text('.non-existent-import-meta-url', metaUrlNonExistent)

  /**
   * don't process the code in the comment
   * const url = new URL('non_existent_file.png', import.meta.url)
   */

  function testDynamicImportMetaUrl(name, i) {
    const metaUrl = new URL(`./nested/${name}.png`, import.meta.url)
    text(`.dynamic-import-meta-url-${i}`, metaUrl)
    document.querySelector(`.dynamic-import-meta-url-img-${i}`).src = metaUrl
  }

  testDynamicImportMetaUrl('icon', 1)
  testDynamicImportMetaUrl('asset', 2)

  function testDynamicImportMetaUrlWithComma(name, i) {
    // prettier-ignore
    const metaUrl = new URL(`./nested/${name}.png`, import.meta.url,)
    text(`.dynamic-import-meta-url-${i}-comma`, metaUrl)
    document.querySelector(`.dynamic-import-meta-url-img-${i}-comma`).src =
      metaUrl
  }

  testDynamicImportMetaUrlWithComma('icon', 1)
  testDynamicImportMetaUrlWithComma('asset', 2)

  function testDynamicImportMetaUrlWithQuery(name, i) {
    // prettier-ignore
    const metaUrl = new URL(`./nested/${name}.png?abc`, import.meta.url,)
    text(`.dynamic-import-meta-url-${i}-query`, metaUrl)
    document.querySelector(`.dynamic-import-meta-url-img-${i}-query`).src =
      metaUrl
  }

  testDynamicImportMetaUrlWithQuery('icon', 1)
  testDynamicImportMetaUrlWithQuery('asset', 2)

  function testDynamicImportMetaUrlWithTernaryOperator(name, i) {
    // prettier-ignore
    const metaUrl = new URL(`./nested/${1 === 0 ? 'failed' : name}.png?abc`, import.meta.url,)
    text(`.dynamic-import-meta-url-${i}-ternary`, metaUrl)
    document.querySelector(`.dynamic-import-meta-url-img-${i}-ternary`).src =
      metaUrl
  }

  testDynamicImportMetaUrlWithTernaryOperator('icon', 1)
  testDynamicImportMetaUrlWithTernaryOperator('asset', 2)

  {
    const name = 'test'
    const js = new URL(`./nested/${name}.js`, import.meta.url).href
    text('.dynamic-import-meta-url-js', js)
  }

  {
    const name = './nested/icon'
    const metaUrl = new URL(`${name}.png`, import.meta.url)
    text(`.dynamic-import-meta-url-all`, metaUrl)
  }

  text('.import-meta-url-multiline', multilineUrl)

  function text(el, text) {
    document.querySelector(el).textContent = text
  }
</script>
